package org.metasketch.simulator.configuration;

import java.io.File;
import java.util.List;

import org.metasketch.demo.model.DEMOModel;
import org.metasketch.demo.project.DEMOProject;
import org.metasketch.simulator.configuration.loaders.DynamicConfigLoader;
import org.metasketch.simulator.configuration.loaders.DynamicResourceConfig;
import org.metasketch.simulator.configuration.loaders.SimulationConfig;
import org.metasketch.simulator.configuration.loaders.SimulationConfigLoader;
import org.metasketch.simulator.configuration.loaders.StaticConfigLoader;
import org.metasketch.simulator.configuration.loaders.StaticResourceConfig;
import org.metasketch.simulator.resources.Resource;
import org.metasketch.simulator.resources.ResourceBank;
import org.metasketch.simulator.tools.Registry;
import org.metasketch.simulator.tools.channels.MainChannelDefinitionLoader;
import org.metasketch.simulator.tools.channels.MainChannelsDefinition;
import org.metasketch.simulator.tools.channels.MainTransactionChannelLoader;
import org.metasketch.simulator.tools.channels.MainTransactionChannels;
import org.metasketch.simulator.tools.channels.dynamic.MainDynamicTransactionChannelLoader;
import org.metasketch.simulator.tools.channels.dynamic.MainDynamicTransactionChannels;
import org.metasketch.simulator.tools.resources.MainResources;
import org.metasketch.simulator.tools.resources.MainResourcesDefinitionLoader;
import org.metasketch.simulator.tools.transactions.MainTransactionDefinitionLoader;
import org.metasketch.simulator.tools.transactions.MainTransactions;
import org.metasketch.simulator.transformation.PetriNetSimulationPackage;

public class MainLoader {

	public SimulationPackage loadSimulationPackaged(DEMOProject project,
			PetriNetSimulationPackage petriNetSimulationPackage)
			throws Throwable {

		// get the folder, test if exists

		DEMOModel model = ((DEMOModel) project.getModel());

		String simFolder = project.getPath() + "//simulation";
		File folder = new File(simFolder);
		if (!folder.exists())
			throw new Exception("Simulation folder doesn't exist ! "
					+ simFolder);

		// get the 3 files, test if they exist
		File simulationConfigFile = null, staticConfigFile = null, dynamicConfigFile = null, resourcesConfigFile = null, channelsConfigFile = null, transactionsConfigFile = null, transactionChannelsConfig = null, distributionTransactionChannelsConfig = null;

		File[] files = folder.listFiles();
		for (File file : files) {
			String name = file.getName();
			if (name.equals("simulation.txt"))
				simulationConfigFile = file;
			else if (name.equals("static resources.xml"))
				staticConfigFile = file;
			else if (name.equals("dynamic resources.xml"))
				dynamicConfigFile = file;
			else if (name.equals("resources.xml"))
				resourcesConfigFile = file;
			else if (name.equals("channels.xml"))
				channelsConfigFile = file;
			else if (name.equals("transactions.xml"))
				transactionsConfigFile = file;
			else if (name.equals("transaction-channels.xml"))
				transactionChannelsConfig = file;
			else if (name
					.equals("dynamic-channel-transaction-distribution.xml"))
				distributionTransactionChannelsConfig = file;
		}

		if (resourcesConfigFile == null)
			throw new Exception(
					"No resources config file resources.xml found in sim folder: "
							+ simFolder);

		if (channelsConfigFile == null)
			throw new Exception(
					"No channels config file channels.xml found in sim folder: "
							+ simFolder);

		if (transactionsConfigFile == null)
			throw new Exception(
					"No transactions config file transactions.xml found in sim folder: "
							+ simFolder);

		if (transactionChannelsConfig == null)
			throw new Exception(
					"No transaction channels config file transaction-channels.xml found in sim folder: "
							+ simFolder);

		if (distributionTransactionChannelsConfig == null)
			throw new Exception(
					"No transaction channels config file dynamic-channel-transaction-distribution.xml found in sim folder: "
							+ simFolder);

		if (simulationConfigFile == null)
			throw new Exception(
					"No sim config file simulation.txt found in sim folder: "
							+ simFolder);

		if (staticConfigFile == null)
			throw new Exception(
					"No static resource config file static resources.xml found in sim folder: "
							+ simFolder);

		if (dynamicConfigFile == null)
			throw new Exception(
					"No dynamic resource config file dynamic resources.xml found in sim folder: "
							+ simFolder);

		// get the files and feed them to the specific loaders

		// add the transformed resources to the registry...
		MainResources resourceConfig = MainResourcesDefinitionLoader
				.getResources(petriNetSimulationPackage, resourcesConfigFile);

		MainChannelsDefinition channelConfig = MainChannelDefinitionLoader
				.getResources(petriNetSimulationPackage, channelsConfigFile);

		MainTransactions transactionConfig = MainTransactionDefinitionLoader
				.getResources(model, petriNetSimulationPackage,
						transactionsConfigFile);

		MainTransactionChannels transactionChannelsConfigClass = MainTransactionChannelLoader
				.getResources(model, petriNetSimulationPackage,
						transactionChannelsConfig);

		MainDynamicTransactionChannels transactionChannelsDistributionConfig = MainDynamicTransactionChannelLoader
				.getResources(model, petriNetSimulationPackage,
						distributionTransactionChannelsConfig);

		SimulationConfig simulationConfig = SimulationConfigLoader
				.load(simulationConfigFile);

		StaticResourceConfig staticResourceConfig = StaticConfigLoader
				.getStaticResources(petriNetSimulationPackage, staticConfigFile);

		DynamicResourceConfig dynamicResourceConfig = DynamicConfigLoader
				.getDynamicResources(model, petriNetSimulationPackage,
						dynamicConfigFile);

		// created the package and return it
		SimulationPackage simulationPackage = new SimulationPackage();

		simulationPackage.setResourceConfig(resourceConfig);
		simulationPackage.setChannelConfig(channelConfig);
		simulationPackage.setTransactionConfig(transactionConfig);
		simulationPackage
				.setTransactionChannelsConfig(transactionChannelsConfigClass);
		simulationPackage
				.setTransactionChannelsDistributionConfig(transactionChannelsDistributionConfig);

		simulationPackage.setSimulationConfig(simulationConfig);
		simulationPackage.setStaticResourceConfig(staticResourceConfig);
		simulationPackage.setDynamicResourceConfig(dynamicResourceConfig);

		return simulationPackage;
	}
}
